package com.squareup.timessquare;

import static java.util.Calendar.DATE;
import static java.util.Calendar.DAY_OF_MONTH;
import static java.util.Calendar.DAY_OF_WEEK;
import static java.util.Calendar.HOUR_OF_DAY;
import static java.util.Calendar.MILLISECOND;
import static java.util.Calendar.MINUTE;
import static java.util.Calendar.MONTH;
import static java.util.Calendar.SECOND;
import static java.util.Calendar.YEAR;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.squareup.timessquare.MonthView.Listener;
import com.yksj.healthtalk.ui.R;

public class CalendarFragment extends Fragment {
	Locale locale;
	MonthView monthView;
	Calendar mCurrentCalendar;
	SimpleDateFormat monthNameFormat;
	SimpleDateFormat weekdayNameFormat;
	SimpleDateFormat dayNameDateFormat;
	Calendar today;
	Date mSelectedDate;//选中的日期
	
	final Map<String,Date> mBusyMap = new HashMap<String, Date>();
	final Map<String,Date> mIdleMap = new HashMap<String, Date>();
	
	//选中的日期
//	final List<Calendar> selectedCals = new ArrayList<Calendar>();
	//月份集合
	final List<MonthDescriptor> months = new ArrayList<MonthDescriptor>();
	//月对应的日期集合
	private final List<List<List<MonthCellDescriptor>>> cells =  new ArrayList<List<List<MonthCellDescriptor>>>();
	
	//当前选中的日期
	MonthCellDescriptor selectedCellDescriptor;
	Listener mListener2;
	
	final Listener mListener = new Listener() {
		@Override
		public void onChangeMonth(int i) {
			if(i > 0){
				onNextMonth();
			}else{
				onPriveMonth();
			}
			if(mListener2 != null)mListener2.onChangeMonth(i);
		}
		@Override
		public void handleClick(MonthCellDescriptor cell) {
			if(selectedCellDescriptor != null){
				selectedCellDescriptor.setSelected(false);
				//cell 对应的对象是否相等
				if(selectedCellDescriptor == selectedCellDescriptor.getCellView().getTag()){
					selectedCellDescriptor.getCellView().setSelected(selectedCellDescriptor.isSelected());
				}
			}
			selectedCellDescriptor = cell;
			mSelectedDate = selectedCellDescriptor.getDate();
			selectedCellDescriptor.setSelected(true);
			selectedCellDescriptor.getCellView().setSelected(selectedCellDescriptor.isSelected());
			if(mListener2 != null)mListener2.handleClick(cell);
		}
	};
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setRetainInstance(true);
		
		locale = Locale.getDefault();
		today = Calendar.getInstance(locale);
		mCurrentCalendar = Calendar.getInstance(locale);
		monthNameFormat = new SimpleDateFormat(getString(R.string.month_name_format), locale);
		weekdayNameFormat = new SimpleDateFormat(getString(R.string.day_name_format), locale);
		dayNameDateFormat = new SimpleDateFormat(getString(R.string.day_time_name_format), locale);
		
		setMidnight(mCurrentCalendar);
		
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		monthView = MonthView.create(container, inflater, weekdayNameFormat,mListener, today);
		final int bg = getResources().getColor(R.color.calendar_bg);
		monthView.setBackgroundColor(bg);
		return monthView;
	}
	
	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		if(cells.size() == 0){
			initCalender(null, null, null,null);
		}
		onUpdateView();
	}
	
	/**
	 * 初始化
	 * @param selectedDate 选中的日期,没有选中传null
	 * @param busyDates 忙
	 * @param idleDates 闲
	 */
	public void initCalender(Date selectedDate,Collection<Date> busyDates,Collection<Date> idleDates,Listener listener){
		this.mListener2 = listener;
		this.mSelectedDate = selectedDate;
		mBusyMap.clear();
		mIdleMap.clear();
		
//		Calendar calendar = Calendar.getInstance();
//		setMidnight(calendar);
//		busyDates = new ArrayList<Date>();
//		busyDates.add(calendar.getTime());
//		calendar.add(Calendar.DATE,1);
//		idleDates = new ArrayList<Date>();
//		idleDates.add(calendar.getTime());
		
		if(busyDates != null){
			for (Date date : busyDates) {
				mBusyMap.put(dayNameDateFormat.format(date),date);
			}
		}
		if(idleDates != null){
			for (Date date : idleDates) {
				mIdleMap.put(dayNameDateFormat.format(date),date);
			}
		}
		if(selectedDate != null){
			mCurrentCalendar.setTime(selectedDate);
		}
		setMidnight(mCurrentCalendar);
		
		onUpdateView();
	}
	
	private void onNextMonth(){
		mCurrentCalendar.add(MONTH,1);
		onUpdateView();
	}
	
	private void onPriveMonth(){
		mCurrentCalendar.add(MONTH,-1);
		onUpdateView();
	}
	
	private void onUpdateView(){
		months.clear();
		cells.clear();
		Date date = mCurrentCalendar.getTime();
		MonthDescriptor month = new MonthDescriptor(
		        		  mCurrentCalendar.get(MONTH), 
		        		  mCurrentCalendar.get(YEAR), 
		        		  date,
		        		  monthNameFormat.format(date));
		months.add(month);
		cells.add(getMonthCells(month,mCurrentCalendar));
		if(monthView != null)monthView.init(months.get(0),cells.get(0));
	}
	
	/**
	 * 获取日期
	 * @param month
	 * @param startCal
	 * @return
	 */
	private List<List<MonthCellDescriptor>> getMonthCells(
			MonthDescriptor month, Calendar startCal) {
		//选中的日期
		Calendar selectedCalendar = null;
		if(mSelectedDate != null){
			selectedCalendar = Calendar.getInstance(locale);
			selectedCalendar.setTime(mSelectedDate);
		}
		
		Calendar cal = Calendar.getInstance(locale);
		cal.setTime(startCal.getTime());
		
		List<List<MonthCellDescriptor>> cells = new ArrayList<List<MonthCellDescriptor>>();
		cal.set(DAY_OF_MONTH, 1);
		
		int firstDayOfWeek = cal.get(DAY_OF_WEEK);
		//计算开始的星期
		int offset = cal.getFirstDayOfWeek() - firstDayOfWeek;
		if (offset > 0) {
			offset -= 7;
		}
		cal.add(Calendar.DATE, offset);
//		Calendar minSelectedCal = minDate(selectedCals);
//		Calendar maxSelectedCal = maxDate(selectedCals);
		//计算日期
		while ((cal.get(MONTH) < month.getMonth() + 1 
				|| cal.get(YEAR) < month.getYear()) && cal.get(YEAR) <= month.getYear()) {
			List<MonthCellDescriptor> weekCells = new ArrayList<MonthCellDescriptor>();
			cells.add(weekCells);
			//计算一周的日期
			for (int c = 0; c < 7; c++) {
				Date date = cal.getTime();
				boolean isCurrentMonth = cal.get(MONTH) == month.getMonth();// 是否是当月
				boolean isSelected = isCurrentMonth && selectedCalendar != null && sameDate(selectedCalendar,cal);// 是否是当月且在选中列表当中
				boolean isSelectable = true;
				/*boolean isSelectable = isCurrentMonth
						&& betweenDates(cal, minCal, maxCal)
						&& isDateSelectable(date);// 是否可以选中
*/				boolean isToday = sameDate(cal, today);// 是否是今天
				int value = cal.get(DAY_OF_MONTH);
				
				// 设置状态
				MonthCellDescriptor.RangeState rangeState = MonthCellDescriptor.RangeState.NONE;
				if(isBusyDate(date)){
					rangeState = MonthCellDescriptor.RangeState.BUSY;
				}else if(isIdleDate(date)){
					rangeState = MonthCellDescriptor.RangeState.IDLE;
				}
				/*if (selectedCals != null && selectedCals.size() > 1) {
					if (sameDate(minSelectedCal, cal)) {
						rangeState = MonthCellDescriptor.RangeState.FIRST;
					} else if (sameDate(maxDate(selectedCals), cal)) {
						rangeState = MonthCellDescriptor.RangeState.LAST;
					} else if (betweenDates(cal, minSelectedCal, maxSelectedCal)) {
						rangeState = MonthCellDescriptor.RangeState.MIDDLE;
					}
				}*/
				MonthCellDescriptor cellDescriptor = new MonthCellDescriptor(date, isCurrentMonth,
						isSelectable, isSelected, isToday, value, rangeState);
				weekCells.add(cellDescriptor);
				if(isSelected){
					selectedCellDescriptor = cellDescriptor;
				}
				cal.add(DATE, 1);
			}
		}
		return cells;
	}
	
	private final boolean isBusyDate(Date date){
		return mBusyMap.containsKey(dayNameDateFormat.format(date));
	}
	
	private final boolean isIdleDate(Date date){
		return mIdleMap.containsKey(dayNameDateFormat.format(date));
	}
	
	private final void setMidnight(Calendar cal) {
		cal.set(HOUR_OF_DAY, 0);
		cal.set(MINUTE, 0);
		cal.set(SECOND, 0);
		cal.set(MILLISECOND, 0);
	}
	
	private static boolean containsDate(List<Calendar> selectedCals, Calendar cal) {
		for (Calendar selectedCal : selectedCals) {
			if (sameDate(cal, selectedCal)) {
				return true;
			}
		}
		return false;
	}
	  
	  /**
	   * 日期比较是否相同
	   * @param cal
	   * @param selectedDate
	   * @return
	   */
	private static boolean sameDate(Calendar cal, Calendar selectedDate) {
		return cal.get(MONTH) == selectedDate.get(MONTH)
				&& cal.get(YEAR) == selectedDate.get(YEAR)
				&& cal.get(DAY_OF_MONTH) == selectedDate.get(DAY_OF_MONTH);
	}
	
}
